package gomodel

import (
	"fmt"
	"reflect"
)

func BeanCopy(targetObject, sourceObject interface{}) error {
	dstValue := reflect.ValueOf(targetObject)
	if dstValue.Kind() != reflect.Ptr || dstValue.IsNil() {
		return fmt.Errorf("destination must be a non-nil pointer")
	}
	srcValue := reflect.ValueOf(sourceObject)
	if srcValue.Kind() != reflect.Ptr || srcValue.IsNil() {
		return fmt.Errorf("source must be a non-nil pointer")
	}
	dstElem := dstValue.Elem()
	srcElem := srcValue.Elem()
	for i := 0; i < dstElem.NumField(); i++ {
		dstField := dstElem.Field(i)
		srcField := srcElem.FieldByName(dstField.String())
		if srcField.IsValid() && srcField.Type().AssignableTo(dstField.Type()) {
			dstField.Set(srcField)
		}
	}

	return nil
}
func BeanCopyVaule(targetObject, sourceObject interface{}) int {
	value := reflect.ValueOf(targetObject)
	if value.Kind() != reflect.Ptr || value.IsNil() {
		return 0
	}
	source := reflect.ValueOf(sourceObject).Elem()
	target := value.Elem()
	if source.Type() != target.Type() {
		return 0
	}
	target.Set(source)
	return target.Len()
}

func BeanClone(obj interface{}) interface{} {
	value := reflect.ValueOf(obj)

	if value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	clone := reflect.New(value.Type()).Elem()
	for i := 0; i < value.NumField(); i++ {
		cloneField := clone.Field(i)
		field := value.Field(i)
		if field.CanInterface() {
			cloneField.Set(field)
		}
	}
	return clone.Addr().Interface()
}
